﻿/****************************************************
	文件：AttributeService.cs
	作者：HuskyT
	邮箱：1005240602@qq.com
	日期：2021/3/26 13:45:10
	功能：TIDService 全局ID生成器 服务
*****************************************************/

using System.Collections.Generic;
using HTFW.Utility.Global;

namespace HTFW.Core
{
    public class TIDService : Singleton<TIDService>, IService, ILateUpdate
    {
        List<TIDCreator> mCache;
        bool mHasInit = false;
        
        public void Init(params object[] args)
        {
            if (mHasInit) return;
            mCache = new List<TIDCreator>();

            mHasInit = true;
        }

        public void Dispose()
        {
            if (!mHasInit) return;
            mCache = null;

            mHasInit = false;
        }

        public TIDCreator GetTIDCreator()
        {
            TIDCreator creator = new TIDCreator();
            mCache.Add(creator);
            return creator;
        }

        public void DestroyTIDCreator(TIDCreator creator)
        {
            if (mCache.Contains(creator))
                mCache.Remove(creator);
        }

        public void OnLateUpdate()
        {
            if (!mHasInit) return;
            foreach (var creator in mCache)
                creator.OnLateUpdate();
        }
    }

    public class TIDCreator : ILateUpdate
    {
        /// <summary>
        /// 全局id
        /// </summary>
        int mTID;

        /// <summary>
        /// 缓存所有全局id
        /// </summary>
        List<int> mTIDs;

        /// <summary>
        /// 缓存使用完了的、待回收的全局id
        /// </summary>
        List<int> mTempRecycleTIDs;

        public TIDCreator()
        {
            mTID = 0;
            mTIDs = new List<int>();
            mTempRecycleTIDs = new List<int>();
        }

        /// <summary>
        /// 生成全局ID
        /// </summary>
        public int Spawn()
        {
            //全局ID自增
            mTID += 1;
            //容错处理：
            //防止int超出上界、防止mTID重复使用
            while (true)
            {
                //达到int上界
                if (mTID == int.MaxValue)
                {
                    //重置
                    mTID = 0;
                }

                //是否使用过的标志位
                bool isUsed = false;
                //遍历缓存，检查mTID是否使用过
                for (int i = 0; i < mTIDs.Count; i++)
                {
                    if (mTIDs[i] == mTID)
                    {
                        //使用过
                        isUsed = true;
                        break;
                    }
                }

                //mTID使用过
                if (isUsed)
                {
                    //自增
                    mTID += 1;
                }
                //mTID没有使用过
                else
                {
                    //添加到缓存
                    mTIDs.Add(mTID);
                    break;
                }
            }

            return mTID;
        }

        public void Despawn(int tid)
        {
            mTempRecycleTIDs.Add(tid);
        }

        public void OnLateUpdate()
        {
            if (mTempRecycleTIDs.Count <= 0) return;
            
            foreach (var tid in mTempRecycleTIDs)
                mTIDs.Remove(tid);
            mTempRecycleTIDs.Clear();
        }
    }
}